/*
 * server.js, all functions need communicate to server. 
 */

var request = null;

/*
 * Wrapper funciton for constructing a request object
 * Parameters:
 * reqType: HTTP request type, e.g. POST or GET.
 * url: the url of the server
 * asynch: whether to send the request asynchronously or not.
 * repHanle: the name of fnuction will to handle the response.
 * data: data will send to the server.
 */
function httpRequest(reqType, url, asynch, repHandle, data) {
    // Mozilla-based browsers
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        // Internet Explorer
        request = new ActiveXObject("Msxml2.XMLHTTP");
        if (!request) {
            request = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    // test for a null request
    if (request) {
        if (reqType.toLowerCase() != "post") {
            initRequest(reqType, url, asynch, repHandle);
        } else {
            if (data != null && data.length > 0) {
                initRequest(reqType, url, asynch, repHandle, data);
            }
        }
    } else {
        alert("Your browser is not support all of this application's features");
    }
}

/** initialize a constructed request object. */
function initRequest(reqType, url, asynch, repHandle, data) {
    try {
        request.onreadystatechange = repHandle;
        request.open(reqType, url, asynch);
        if (reqType.toLowerCase() == "post") {
            request.setRequestHeader("If-Modified-Since", "0");
            request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
            request.send(data);
        } else {
            request.send(null);
        }
    } catch (errv) {
        alert("Cannot contact server at the moment, please try later.\n Error detial: " +  errv.message);
    }
}

/* ------------------------------------------------------------------------ */
/* handle the reponse of create new project request */
function createProjectCallback() {
    if (request.readyState == 4) {
        if (request.status == 200) {
            var pid = request.responseText;
            if (pid == "failed") {
                alert("Can not create new project, try later please.");
                return false;
            } else {
                globalVar.projectId = pid;
                OAT.Dom.show(globalVar.canvas);
            }
        } else {
            alert(request.status + ": A problem occurred with communicating to the server program.");
        }
    }
}

/** create a new project. */
function createProject() {
    var url = "createProject.do";
    httpRequest("GET", url, true, createProjectCallback, null);
}

/* handle the reponse of create new project request */
function closeProjectCallback() {
    if (request.readyState == 4) {
        if (request.status == 200) {
            var pid = request.responseText;
            if (pid == "failed") {
                alert("Can not close new project, try later please.");
                return;
            } else {
                globalVar.projectId = false;
                globalVar.dbView.clear();
                globalVar.ontoView.clear();
                OAT.Dom.hide(globalVar.canvas);
            }
        } else {
            alert(request.status + ": A problem occurred with communicating to the server program.");
        }
    }
}

/** close current project. */
function closeProject() {
    var close = confirm("Close current project?");
    if (close) {
        var url = "closeProject.do?pid=" + globalVar.projectId;
        httpRequest("GET", url, true, closeProjectCallback, null);
    }
}

/************************** get Dbres infos. *************************/
function parseDbResDom(doc) {
    if (!doc)
        return;
    globalVar.dbs.length = 0;
    var tableCount = 0;
    var root = doc.documentElement;
    var dbs = root.childNodes;
    for (var i = 0; i < dbs.length; i++) {
        var dbUri = dbs[i].getAttribute("uri");
        var dbres = new Database(dbUri);
        var tables = dbs[i].childNodes;
        for (var j = 0; j < tables.length; j++) {
            var tableUri = tables[j].getAttribute( "uri");
            var tableName = tables[j].getAttribute("name");
            var table = new Table(tableUri, tableName, tableCount);
            tableCount++;
            var columns = tables[j].childNodes;
            for (var k = 0; k < columns.length; k++) {
                var columnName = columns[k].firstChild.nodeValue;
                var column = new Column(tableUri + "." + columnName, columnName);
                table.addColumn(column);
            }
            dbres.addTable(table);
        }
        globalVar.dbs.push(dbres);
        globalVar.dbView.addDb(dbres);
    }
}

function getDbresCallback() {
    if (request.readyState == 4) {
        if (request.status == 200) {
            var doc = request.responseXML;
            parseDbResDom(doc);
        } else {
            alert(request.status + ": A problem occurred with communicating to the server program.");
        }
    }
}

function getDbres() {
    var url = "getDbres.do";
    var param = "pid=" + globalVar.projectId;
    httpRequest("POST", url, true, getDbresCallback, param);
}

/*********************** get onto infos. ******************************/
/** check the onlogy is exist. */
function isExsit(uri) {
    for (var i = 0; i < globalVar.ontos.length; i++) {
        if (globalVar.ontos[i].uri == uri)
            return (i + 1);
    }
    return false;
}

/** parse DOM structure and stores ontology infos. */
function parseOntoDom(doc) {
    if (!doc)
        return;
    globalVar.ontos.length = 0;
    var root = doc.documentElement;
    var ontos = root.childNodes;
    for (var i = 0; i < ontos.length; i++) {
        var ontoUri = ontos[i].getAttribute("uri");
        var ontoName = ontos[i].getAttribute("name");
        var ontology = false;
        var index = isExsit(ontoUri);
        if (index) {
            ontology = globalVar.ontos[index - 1];
        } else {
            ontology = new Ontology(ontoUri, ontoName);
        }
        var children = ontos[i].childNodes;
        for (var j = 0; j < children.length; j++) {
            var type = children[j].nodeName;
            if (type == "props") {
                var props = children[j].childNodes;
                for (var k = 0; k < props.length; k++) {
                    var propUri = props[k].getAttribute("uri");
                    var propName = props[k].getAttribute("name");
                    var prop = new Property(propUri, propName);
                    ontology.addProperty(prop);
                }
            } else if (type == "objects") {
                var objects = children[j].childNodes;
                for (var k = 0; k < objects.length; k++) {
                    var objectUri = objects[k].getAttribute("uri");
                    var objectName = objects[k].getAttribute("name");
                    var propUri = objects[k].getAttribute("propUri");
                    var idx = isExsit(objectUri);
                    if (idx) {
                        var obj = new OntoObject(globalVar.ontos[idx - 1], propUri);
                        ontology.addObject(obj);
                    } else {
                        var onto = new Ontology(objectUri, objectName);
                        globalVar.ontos.push(onto);
                        var obj = new OntoObject(onto, propUri);
                        ontology.addObject(obj);
                    }
                }
            }
        }
        globalVar.ontos.push(ontology);
    }
    for (var i = 0; i < globalVar.ontos.length; i++) {
        globalVar.ontoView.addOnto(globalVar.ontos[i]);
    }
}

function getOntoCallback() {
    if (request.readyState == 4) {
        if (request.status == 200) {
            var doc = request.responseXML;
            parseOntoDom(doc);
        } else {
            alert(request.status + ": A problem occurred with communicating to the server program.");
        }
    }
}

function getOnto() {
    var url = "getOnto.do";
    var parameter = "pid=" + globalVar.projectId;
    httpRequest("POST", url, true, getOntoCallback, parameter);
}

function submitInfoCallback() {
    if (request.readyState == 4) {
        if (request.status == 200) {
            var file = request.responseText;
            url = "getFile.do?pid=" + globalVar.projectId + "&type=semreg&file=" + file;
            window.open(url);
        } else {
            alert(request.status + ": A problem occurred with communicating to the server program.");
        }
    }
}

function submitInfo(xml, file) {
    var url = "submitMappingInfo.do";
    var parameter = "pid=" + globalVar.projectId + "&file=" + file + "&xml=" + xml;
    httpRequest("POST", url, true, submitInfoCallback, parameter);
}
